package io.renren.modules.rabbitmq.confirm;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;

/**
 * @Author：T-weiwei
 * @Description: 高可靠确认
 * @Email：tweiwei@aliyun.com
 * @CreateDate：2022-01-27-上午10:13
 * @CopyRight：http://www.huaxun.ink/
 * @Hint： This content is limited to the internal circulation of HuaXun Hi Tech Co., Ltd.,
 * and is forbidden to be leaked and used for other commercial purposes
 **/

@Service
public class ConfirmProvider implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnCallback {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init() {
        this.rabbitTemplate.setReturnCallback(this);
        this.rabbitTemplate.setConfirmCallback(this);
    }

    /**
     * 消息从 producer 到 rabbitmq broker有一个 confirmCallback 确认模式
     * @param correlationData 对象内部只有一个 id 属性，用来表示当前消息的唯一性
     * @param ack 消息投递到broker 的状态，true表示成功
     * @param cause 表示投递失败的原因
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (ack) {
            System.out.println("RabbitMQ确认了这条消息：" + correlationData);
        } else {
            // TODO 发送失败后的补救操作
            System.out.println("确认失败了："+correlationData+"；出现异常："+cause);
        }
    }

    /**
     * 如果消息未能投递到目标 queue 里将触发回调 returnCallback ，一旦向 queue 投递消息未成功，这里一般会记录下当前消息的详细投递数据
     * @param message 消息体
     * @param replyCode 错误码
     * @param replyText 错误码描述
     * @param exchange 交换机
     * @param routingKey 队列
     */
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        System.out.println("这条消息由Exchange到queue时发送失败了" + message + ",请处理");
        // TODO queue拒绝后的业务操作
    }

}
